package descentFly.controller
{
	import UIAway.uif_view;
	
	import UIFree.ObjectEvent;
	
	import away3d.animators.data.NullAnimation;
	
	import descentFly.away3D4.chips.df_chipAway;
	import descentFly.away3D4.df_awaySpace;
	import descentFly.chips.df_chip;
	import descentFly.df_space;
	
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Matrix3D;
	import flash.geom.Point;
	import flash.geom.Transform;
	import flash.geom.Vector3D;
	
	import jiglib.physics.RigidBody;

	public class myFlyController extends df_userController {
		public static const FREEZEMYCONTROLLER: String = 'FREEZEMYCONTROLLER';
		
		private var _mousePos		: Vector3D;
		private var _keyMap			: Object;
		private var _startPosition	: Object;
		private var _freeze			: Boolean;
		
		private static var _instance: myFlyController; 

		public function myFlyController(a_stage			: Stage,
									   	a_space			: df_space,
									   	a_options		: Object=null,
									   	dispatchTarget	: EventDispatcher=null,
									   	a_keyMap		: Object = null) {
			super(a_stage, a_space, dispatchTarget?dispatchTarget:a_space, a_options);
			_keyMap		= a_keyMap?a_keyMap:defaultKeyMap();
			_instance 	= this;
		}
		
		public static function instance(): myFlyController {
			return _instance;
		}
		
		public static function create(a_stage			: Stage,
									  a_space			: df_space,
									  a_options			: Object): myFlyController {
			return new myFlyController(a_stage, a_space, a_options);
		}
			
		protected function defaultKeyMap(): Object {
			return {
				40: ACTION_ROTAX,
				38: ACTION_ROTDX,
				39: ACTION_ROTAY,
				37:	ACTION_ROTDY,
				32: ACTION_FIRE,
				87: ACTION_FORWARD,
				83: ACTION_BACKWARD,
				65: ACTION_LEFTROLL,
				68:	ACTION_RIGHTROLL,
//				81: ACTION_NEXTLEVEL,
				69: ACTION_SLIDERIGHT,
				81: ACTION_SLIDELEFT,
				76: ACTION_DECLIVE,
				219: ACTION_WEAPONTPREV,
				221: ACTION_WEAPONTNEXT
			}
		}
		
		override protected function initialize(): void {
			super.initialize();
			_freeze		= false;
			_mousePos	= getMousePos();
		}
		
		protected function doFreeze(e: ObjectEvent): void {
			_freeze = e.object as Boolean;
			if (_freeze) resetKeyState();
			super.changeActionState(ACTION_NOACTIVE, _freeze);
		}
		
		override protected function listenEvents(): void {
			super.listenEvents();
			stage.addEventListener(MouseEvent.MOUSE_MOVE, doMove);
			stage.addEventListener(MouseEvent.MOUSE_UP, doUp);
			stage.addEventListener(KeyboardEvent.KEY_DOWN, doKeyDown);
			stage.addEventListener(KeyboardEvent.KEY_UP, doKeyUp);
			
			stage.addEventListener(Event.DEACTIVATE, doDeactivate);
			stage.addEventListener(Event.ACTIVATE, doActivate);
			stage.addEventListener(FREEZEMYCONTROLLER, doFreeze);
			
			Space.app.addEventListener(MouseEvent.MOUSE_DOWN, doDown);
			Space.addEventListener(df_space.SETMYCHIP, doSetMyChip);
			Space.addEventListener(df_awaySpace.START_POSITION, doStartPosition);
		}

		override protected function removeEvents(): void {
			super.removeEvents();
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, doMove)
			stage.removeEventListener(MouseEvent.MOUSE_UP, doUp);
			stage.removeEventListener(KeyboardEvent.KEY_DOWN, doKeyDown);
			stage.removeEventListener(KeyboardEvent.KEY_UP, doKeyUp);
			
			stage.removeEventListener(Event.DEACTIVATE, doDeactivate);
			stage.removeEventListener(Event.ACTIVATE, doActivate);
			stage.removeEventListener(FREEZEMYCONTROLLER, doFreeze);
			
			Space.app.removeEventListener(MouseEvent.MOUSE_DOWN, doDown);
			Space.removeEventListener(df_space.SETMYCHIP, doSetMyChip);
			Space.removeEventListener(df_awaySpace.START_POSITION, doStartPosition);
		}
		
		private function doDeactivate(e: Event): void {
			resetKeyState();
			changeActionState(ACTION_NOACTIVE, true);
		}
		
		private function doActivate(e: Event): void {
			changeActionState(ACTION_NOACTIVE, false);
		}
		
		protected function doStartPosition(e: ObjectEvent): void {
			_startPosition = e.object;
			bodyToStart();
		}
		
		protected function bodyToStart(): void {
			if (_body && _startPosition) {
				var ca: df_chipAway = _body as df_chipAway;
				ca.body.currentState.orientation = _startPosition.orientation;
				ca.body.currentState.position = _startPosition.position;
				
				var mat: Matrix3D = _startPosition.orientation.clone();
				mat.appendTranslation(_startPosition.position.x, _startPosition.position.y, _startPosition.position.z);
				ca.body.skin.transform = mat;
				_startPosition = null;
			}
		}
		
		override public function dispose():void {
			super.dispose();
			_instance = null;
		}
		
		protected function doSetMyChip(e: ObjectEvent): void {
			_body = e.object as df_chip;
			bodyToStart();
		}
		
		private function doKeyDown(e: KeyboardEvent): void {
			if (!_freeze && _keyMap.hasOwnProperty(e.keyCode)) {
				var stateName: String = _keyMap[e.keyCode];
				changeActionState(stateName, true);
			}
			
			trace(e.keyCode);
		}
		
		private function doKeyUp(e: KeyboardEvent): void {
			if (!_freeze && _keyMap.hasOwnProperty(e.keyCode)) {
				var stateName: String = _keyMap[e.keyCode];
				changeActionState(stateName, false);
			}
		}
		
		private function getMousePos(): Vector3D {
			return new Vector3D(stage.mouseY, stage.mouseX, 0);
		}
		
		override protected function changeActionState(actionName:String, a_state:Object):void {
			if ((Space as df_awaySpace).view.renderEnabled) 
				super.changeActionState(actionName, a_state);
		}
		
		protected function doDown(e: MouseEvent): void {
			if (!_freeze) _mousePos = getMousePos();
		}
		
		protected function doUp(e: MouseEvent): void {
			changeActionState(df_userController.ACTION_ROTATE, null);
			_mousePos = null;
		}
		
		protected function doMove(e: MouseEvent): void {
			if (!_freeze && e.buttonDown && _mousePos) {
				var newPos: Vector3D = getMousePos();
				var delta: Vector3D = newPos.subtract(_mousePos);
				changeActionState(df_userController.ACTION_ROTATE, [delta.x, delta.y, delta.z]);
				_mousePos = newPos;
			}
		}
		
		override public function setBody(a_body: df_chip): void {
			super.setBody(a_body);
			Space.setMyCurrentChip(a_body);
		}
	}
}